package cn.itsource.hrm.service.impl;

import cn.itsource.hrm.constant.RedisConstant;
import cn.itsource.hrm.domain.CourseType;
import cn.itsource.hrm.mapper.CourseTypeMapper;
import cn.itsource.hrm.service.ICourseTypeService;
import cn.itsource.hrm.util.AssertUtils;
import cn.itsource.hrm.vo.CrumbsVO;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author kai
 * @since 2021-01-18
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisTemplate<String,String> template;


    // 新增 修改 和 删除，我们自己重新方法，提供增强的功能，删除缓存
    @Override
    @CacheEvict(value = RedisConstant.COURSE_TYPE_TREE_DATA,key = "'ALL'")
    public boolean insert(CourseType entity) {
        boolean insert = super.insert(entity);
        //template.delete(RedisConstant.COURSE_TYPE_TREE_DATA);
        return insert;
    }

    @Override
    @CacheEvict(value = RedisConstant.COURSE_TYPE_TREE_DATA,key = "'ALL'")
    public boolean deleteById(Serializable id) {
        //template.delete(RedisConstant.COURSE_TYPE_TREE_DATA);
        return super.deleteById(id);
    }

    @Override
    @CacheEvict(value = RedisConstant.COURSE_TYPE_TREE_DATA,key = "'ALL'")
    public boolean updateById(CourseType entity) {
        //template.delete(RedisConstant.COURSE_TYPE_TREE_DATA);
        return super.updateById(entity);
    }

    // 1.先查询redis
    // 2. 如果redis有的就直接返回结果
    // 3. 如果没有，就到数据库进行查询
    // 4. 查询之后，把结果放到Reids
    // 5. 返回结果;
    @Override
    @Cacheable(value = RedisConstant.COURSE_TYPE_TREE_DATA,key = "'ALL'")
    public List<CourseType> treeData() {
        // getCourseTypesByRedis();  手动的自己实现缓存
        System.out.println("======没走缓存，进行方法的调用=======");
        return method3();
    }


    private List<CourseType> getCourseTypesByRedis() {
        // 第一种方式： 递归
        //return selectTypsByPid(0L);
        // 第二种方法： mybatis 提供的嵌套查询
        //return baseMapper.getTreeByPId(0L);
        // 第三种方法：
        List<CourseType> list = null;
        // 1.先查询redis
        String str = template.opsForValue().get(RedisConstant.COURSE_TYPE_TREE_DATA);
        if(StringUtils.isEmpty(str)){
            // 3. 如果没有，就到数据库进行查询
            list = method3();
            // 4. 查询之后，把结果放到Reids
            template.opsForValue().set(RedisConstant.COURSE_TYPE_TREE_DATA, JSON.toJSONString(list));
            // 5. 返回结果;
            System.out.println("=======通过缓存进行查询===========");
        }else{
            // 2. 如果redis有的就直接返回结果
            list = JSON.parseArray(str,CourseType.class);
        }

        return list;
    }

    private List<CourseType> method3() {
        List<CourseType> first = new ArrayList<>();
        //1. 查询所有
        List<CourseType> all = baseMapper.selectList(null);

        //2. 循环所有的type, 找到第一层
        for (CourseType courseType : all) {
            if(courseType.getPid()==0){
                first.add(courseType);
            }else{
                //3. 除了第一层意外的都各自去找自己的上一层；
                for (CourseType parent : all) {
                    Long pid = courseType.getPid();
                    if(pid!=null&&pid.equals(parent.getId())){
                        parent.getChildren().add(courseType);
                    }
                }
            }
        }
        //4. 最终只用返回第一层结果
        return first;
    }

    // 查询的递归方法
    public List<CourseType> selectTypsByPid(Long pid){
        // 1. 先查询所有的第一级 4个 firstTypes
        List<CourseType> list = baseMapper.selectByPId(pid);
        // 2. 遍历firstTypes,根据id,查询pid=first.id,
        for (CourseType courseType : list) {
            //查询第二级 secondTyps；
            List<CourseType> children = selectTypsByPid(courseType.getId());
            if(children!=null){
                // 把下层（第二级）的分类添加到上层（一级）
                courseType.setChildren(children);
            }
        }
        return list;
    }


    /**
     * 查询面包屑
     * @return
     */
    @Override
    public List<CrumbsVO> crumb(Long id) {
        // 1. 判断id不可为空
        AssertUtils.isnotNull("分类id不可为空",id);
        // 2. 根据id查询分类信息
        CourseType courseType = baseMapper.selectById(id);
        // 3. 判断分类信息是否存在
        AssertUtils.isnotNull("分类不存在!!",courseType);
        // 4. 根据 path 1037.1039.1047,查询上级的兄弟
        String path = courseType.getPath();
        String[] split = path.split("\\.");
        List<CrumbsVO> result = new ArrayList<>();
        for (String path_id : split) {
            // 5. 封装对象
            CrumbsVO crumbsVO = new CrumbsVO(); //1037
            // 查自己
            CourseType parentType = baseMapper.selectById(path_id);
            crumbsVO.setOwnerProductType(parentType);
            // 查兄弟
            crumbsVO.setOtherProductTypes(baseMapper.selectByPIdforBother(parentType.getPid()));
            result.add(crumbsVO);
        }

        return result;
    }

    public static void main(String[] args) {
        String str = "a.b.c";
        String[] split = str.split("\\.");
        System.out.println(split[0]);
        System.out.println(split[1]);
        System.out.println(split[2]);

    }
}
